package org.dormi.learn.primitive;


import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.dormi.learn.utils.Assert;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * 钱 = 数量 + 币种
 *
 * @author : dormi330
 * @version : 1.0
 */
public class Money extends _Primitive_ implements Comparable<Money> {

    private final BigDecimal amount;
    private final Currency currency;

    /* === constructor === */
    /* === constructor === */
    /* === constructor === */

    public Money(BigDecimal amount, Currency currency) {
        Assert.isNotNull(amount, "不能为null: Money.amount");
        Assert.isNotNull(currency, "不能为null: Money.currency");

        this.amount = amount;
        this.currency = currency;
    }

    @JsonCreator
    public Money(@JsonProperty("amount") String amount, @JsonProperty("currency") Currency currency) {
        this(new BigDecimal(amount), currency);
    }

    /* === constructor === */
    /* === constructor === */
    /* === constructor === */

    @Override
    public String toString() {
        return String.format("%s:%s", currency.getCode(), amount);
    }

    @Override
    public int compareTo(Money other) {
        if (!Objects.equals(other.currency, currency)) {
            throw new RuntimeException("必须使用同样的货币单位");
        }
        return amount.compareTo(other.amount);
    }

    /* === hash/equals === */
    /* === hash/equals === */
    /* === hash/equals === */

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Money)) return false;
        Money money = (Money) o;
        return amount.compareTo(((Money) o).getAmount()) == 0 &&
                Objects.equals(getCurrency(), money.getCurrency());
    }

    @Override
    public int hashCode() {
        return Objects.hash(
                getAmount().toString(),
                getCurrency().getCode()
        );
    }

    /* === set/get === */
    /* === set/get === */
    /* === set/get === */

    public BigDecimal getAmount() {
        return amount;
    }

    public Currency getCurrency() {
        return currency;
    }
}
